var propertyPanel;
$(function() {
    propertyPanel = new Vue({
        el: '#attribute-panel',
        data: {
            init: false,
            go: {},
            diagram: {},
            goJson: {
                class: 'go.GraphLinksModel',
                linkFromPortIdProperty: 'fromPort',
                linkToPortIdProperty: 'toPort',
                nodeDataArray: [],
                linkDataArray: []
            },
            goJsonData: '',
            nodeProperties: [],
            linkProperties: [],
            currentNode: {
                key: '0',
                text: 'abc',
                loc: '10 -39'
            },
            currentLinke: {
                from: '',
                to: '',
                fromPort: '',
                toPort: '',
                points: []
            }
        },
        methods: {
            save: function() {
                this.goJsonData = this.diagram.model.toJSON()
            },
            load: function() {
                this.diagram.model = this.go.Model.fromJson(this.goJsonData);
            }
        }
    });
});

function init() {
    var g$ = go.GraphObject.make;

    myDiagram =
       g$(go.Diagram, "myDiagramDiv",
        {
          initialContentAlignment: go.Spot.Center,
          allowDrop: true,
          "LinkDrawn": showLinkLabel,
          "LinkRelinked": showLinkLabel,
          "animationManager.duration": 800,
          "undoManager.isEnabled": true
    });

    propertyPanel.$data.go = go;
    propertyPanel.$data.diagram = myDiagram;

    myDiagram.addDiagramListener("Modified", function(e) {
        var button = document.getElementById("SaveButton");
        if (button) button.disabled = !myDiagram.isModified;
    });

    function nodeStyle() {
        return [
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            {
                locationSpot: go.Spot.Center,
                mouseEnter: function (e, obj) { showPorts(obj.part, true); },
                mouseLeave: function (e, obj) { showPorts(obj.part, false); }
            }
        ];
    }

    function makePort(name, spot, output, input) {
        return g$(go.Shape, "Circle",
            {
                fill: "transparent",
                stroke: null,
                desiredSize: new go.Size(8, 8),
                alignment: spot, alignmentFocus: spot,
                portId: name,
                fromSpot: spot, toSpot: spot,
                fromLinkable: output, toLinkable: input,
                cursor: "pointer" 
        });
    }


    var lightText = 'whitesmoke';

    myDiagram.nodeTemplateMap.add("",
       g$(go.Node, "Spot", nodeStyle(),
           g$(go.Panel, "Auto",
                g$(go.Shape, "Rectangle",
                new go.Binding("fill", "fill"),
                new go.Binding("stroke", "stroke"),
                new go.Binding("figure", "figure")),
           g$(go.TextBlock,
            {
              font: "bold 11pt Helvetica, Arial, sans-serif",
              stroke: lightText,
              margin: 8,
              maxSize: new go.Size(160, NaN),
              wrap: go.TextBlock.WrapFit,
              editable: true
            },
            new go.Binding("text").makeTwoWay()),
            {
                click: function(e, node) {
                    propertyPanel.currentNode = node.part.data;
                }
            }
        ),

        makePort("T", go.Spot.Top, false, true),
        makePort("L", go.Spot.Left, true, true),
        makePort("R", go.Spot.Right, true, true),
        makePort("B", go.Spot.Bottom, true, false)
    ));

    myDiagram.nodeTemplateMap.add("Start",
       g$(go.Node, "Spot", nodeStyle(),
           g$(go.Panel, "Auto",
           g$(go.Shape, "Circle",
            { minSize: new go.Size(40, 40), fill: "#79C900", stroke: null }),
           g$(go.TextBlock, "Start",
            { font: "bold 11pt Helvetica, Arial, sans-serif", stroke: lightText },
            new go.Binding("text")),
            {
                click: function(e, node) {
                    propertyPanel.currentNode = node.part.data;
                }
            }
        ),

        makePort("L", go.Spot.Left, true, false),
        makePort("R", go.Spot.Right, true, false),
        makePort("B", go.Spot.Bottom, true, false)
    ));

    myDiagram.nodeTemplateMap.add("End",
       g$(go.Node, "Spot", nodeStyle(),
           g$(go.Panel, "Auto",
           g$(go.Shape, "Circle",
            { minSize: new go.Size(40, 40), fill: "#DC3C00", stroke: null }),
           g$(go.TextBlock, "End",
            { font: "bold 11pt Helvetica, Arial, sans-serif", stroke: lightText },
            new go.Binding("text")),
            {
                click: function(e, node) {
                    propertyPanel.currentNode = node.part.data;
                }
            }
        ),

        makePort("T", go.Spot.Top, false, true),
        makePort("L", go.Spot.Left, false, true),
        makePort("R", go.Spot.Right, false, true)
    ));

    myDiagram.nodeTemplateMap.add("Comment",
       g$(go.Node, "Auto", nodeStyle(),
           g$(go.Shape, { figure: "RoundedRectangle", fill: "lightgreen" }),
           g$(go.TextBlock,
            {
                margin: 5,
                maxSize: new go.Size(200, NaN),
                wrap: go.TextBlock.WrapFit,
                textAlign: "center",
                editable: true,
                font: "bold 12pt Helvetica, Arial, sans-serif",
                stroke: '#454545'
            },
            new go.Binding("text").makeTwoWay(),
            {
                click: function(e, node) {
                    propertyPanel.currentNode = node.part.data;
                }
            }
        )
    ));


    myDiagram.linkTemplate =
       g$(go.Link,
        {
            routing: go.Link.AvoidsNodes,
            curve: go.Link.JumpOver,
            corner: 5, toShortLength: 4,
            relinkableFrom: true,
            relinkableTo: true,
            reshapable: true,
            resegmentable: true,

            mouseEnter: function(e, link) { link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)"; },
            mouseLeave: function(e, link) { link.findObject("HIGHLIGHT").stroke = "transparent"; }
        },
        new go.Binding("points").makeTwoWay(),
       g$(go.Shape,
            { isPanelMain: true, strokeWidth: 8, stroke: "transparent", name: "HIGHLIGHT" }),
       g$(go.Shape,
            { isPanelMain: true, stroke: "gray", strokeWidth: 2 },
            new go.Binding("stroke", "stroke")),
       g$(go.Shape,
            { toArrow: "standard", stroke: null, fill: "gray"},
            new go.Binding("fill", "fill")),
       g$(go.Panel, "Auto",
            { visible: false, name: "LABEL", segmentIndex: 2, segmentFraction: 0.5},
            new go.Binding("visible", "visible").makeTwoWay(),
           g$(go.Shape, "RoundedRectangle",
                { fill: "#F8F8F8", stroke: null }),
           g$(go.TextBlock, "Yes", 
            {
                textAlign: "center",
                font: "10pt helvetica, arial, sans-serif",
                stroke: "#333333",
                editable: true
            },
            new go.Binding("text").makeTwoWay())
        ),
        {
            click: function(e, node) {
                propertyPanel.currentNode = node.part.data;
            }
        }
    );

    function showLinkLabel(e) {
        var label = e.subject.findObject("LABEL");
        if (label !== null) label.visible = (e.subject.fromNode.data.figure === "Diamond");
    }

    myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
    myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;

    myPalette =
       g$(go.Palette, "myPaletteDiv", 
        {
            "animationManager.duration": 800,
            nodeTemplateMap: myDiagram.nodeTemplateMap,
            model: new go.GraphLinksModel([
                { category: "Start", text: "Start" },
                { text: "Step", fill: 'mediumseagreen', stroke: null },
                { text: "???", fill: '#20b3ad', stroke: 'gray', figure: "Diamond" },
                { category: "End", text: "End" },
                { category: "Comment", text: "Comment" }
            ])
    });
}

function showPorts(node, show) {
    var diagram = node.diagram;
    if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;
    node.ports.each(function(port) {
        port.stroke = (show ? "white" : null);
    });
}